package com.kmt.plaza.sevice.impl;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.kmt.plaza.dao.SwiperMapper;
import com.kmt.plaza.entity.ProductImg;
import com.kmt.plaza.entity.Swiper;
import com.kmt.plaza.sevice.SwiperService;
import com.kmt.plaza.vo.ResStatus;
import com.kmt.plaza.vo.ResultVO;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

@Service
public class SwiperServiceImpl implements SwiperService {

    @Autowired
    private SwiperMapper swiperMapper;
    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    @Autowired
    private ObjectMapper objectMapper = new ObjectMapper();
    private Logger logger = LoggerFactory.getLogger(SwiperServiceImpl.class);
    @Override
    public ResultVO listSwipers() {
        logger.info("查询首页轮播图开始......");
        List<Swiper> swipers = null;
        try{
            //String结构缓存轮播图信息
            //示例1000个请求查询到redis中的数据都为null，缓存击穿
            String imgStr = stringRedisTemplate.boundValueOps("swipers").get();
            if(imgStr != null){
                //从redis中获取到数据返回到前端
                logger.info("redis中获取到了首页轮播图信息......");
                JavaType javaType = objectMapper.getTypeFactory().constructParametricType(ArrayList.class, Swiper.class);
                swipers = objectMapper.readValue(imgStr, javaType);
            }else{
                logger.info("redis中未获取到首页轮播图.....");
                //redis中没有查到数据，则查询数据库
                //示例这1000个请求都会进入else访问数据库
                synchronized (this){
                    //第二次查询redis
                    logger.info("第二次查询redis获取到首页轮播图开始......");
                    String imgStr1 = stringRedisTemplate.boundValueOps("swipers").get();
                    if(imgStr1 == null){
                        logger.info("第二次查询redis,redis中仍然没有获取到首页轮播图信息，开始查询数据库......");
                        //如果redis任然未获取到，就开始查询数据库
                        swipers = swiperMapper.listSwipers();
                        //将数据库中查到的数据保存到redis中
                        if(swipers != null){
                            stringRedisTemplate.boundValueOps("swipers").set(objectMapper.writeValueAsString(swipers));
                            stringRedisTemplate.boundValueOps("swipers").expire(1, TimeUnit.DAYS);
                        }else{
                            //如果数据库没有查到会产生缓存穿透
                            List<Swiper> arr = new ArrayList<>();
                            //写一个值到redis中
                            stringRedisTemplate.boundValueOps("swipers").set(objectMapper.writeValueAsString(arr));
                            //设置过期时间，为检测10秒后有无这个轮播图
                            stringRedisTemplate.boundValueOps("swipers").expire(10, TimeUnit.SECONDS);
                        }
                    }else{
//                        System.out.println("=============查询redis有数据");
                        //将Swiper转为数组
                        JavaType javaType = objectMapper.getTypeFactory().constructParametricType(ArrayList.class, Swiper.class);
                        swipers = objectMapper.readValue(imgStr1, javaType);
                    }
                }

            }
        }catch (JsonProcessingException e){
            e.printStackTrace();
        }
        //返回数据
        if(swipers != null){
            return new ResultVO(ResStatus.OK,"success",swipers);
        }else{
            return new ResultVO(ResStatus.NO,"fail",null);
        }
    }
}
